package com.bckj.fastboot.core.util;

import com.bckj.fastboot.core.lang.func.VoidFunc2;
import lombok.SneakyThrows;

import java.util.Collection;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 合并工具
 */
public class MergeUtils {




    /**
     * 合并两个集合。
     * <p>
     *     集合1和集合2的元素key相同，则合并集合1的元素。
     * </p>
     * <b>示例代码：</b>
     * <pre>
     * class A {
     *     private Long id;
     *     private String name;
     *     private Long bid;
     *     private String sex;
     * }
     * class B {
     *     private Long id;
     *     private String sex;
     * }
     * public static void main(String[] args) {
     *     var list1 = List.of(new A(1,"张三",11), new A(2,"李四",22));
     *     var list2 = List.of(new B(11,"男"), new B(22,"女"));
     *     MergeUtils.mergeColl(list1, list2, A::getBid, B::getId, (a, b) -> a.setSex(b.getSex()));
     *     System.out.println(list1);
     * }
     * </pre>
     *
     * @param coll1 集合1
     * @param coll2 集合2
     * @param keyFunc1 集合1 元素key
     * @param keyFunc2 集合2 元素key
     * @param func2 操作方法
     * @param <T1> 集合1 元素泛型
     * @param <T2> 集合2 元素泛型
     * @param <K> 元素key泛型
     */
    @SneakyThrows
    public static <T1, T2, K> void mergeColl(Collection<T1> coll1, Collection<T2> coll2, Function<T1, K> keyFunc1, Function<T2, K> keyFunc2, VoidFunc2<T1, T2> func2) {
        Map<K, T2> map =
                coll2.stream().collect(Collectors.toMap(keyFunc2, Function.identity(), (v1, v2) -> v1));
        mergeCollMap(coll1, map, keyFunc1, func2);
    }

    public static <T1, T2, K> void mergeCollMap(Collection<T1> coll1, Map<K, T2> map, Function<T1, K> keyFunc1, VoidFunc2<T1, T2> func2) {
        for (T1 t1 : coll1) {
            var key1 = keyFunc1.apply(t1);
            var t2 = map.get(key1);
            func2.call(t1, t2);
        }
    }
}
